package com.own.demo.writerfile;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.own.demo.utils.CommWriterFileInfo;
import com.own.demo.utils.DateUtils;
import com.own.demo.utils.FileToStringUtils;
import com.own.demo.vo.Bounds;
import com.own.demo.vo.NodeInfo;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.BufferedWriter;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class 油管项目OsmXML {
    private static AtomicLong indexNum = new AtomicLong(1);
    private static Map<String, NodeInfo> lonLatMap;
    static String geoOSMUrl = "D:\\dkSpace\\油库规划\\路网\\";
    static String geoOSMName = "all-gaode-"+ DateUtils.getNewDateSs() +".osm";

    public static void main(String[] args) {
        String jsonPath = "C:\\Users\\heyou\\Desktop\\路网数据00.geojson";
        String data = FileToStringUtils.txt2String(new File(jsonPath));
        JSONObject geoJson = JSONObject.parseObject(data);


        List<Double> lonList = new ArrayList<>(1000000);
        List<Double> latList = new ArrayList<>(1000000);

        JSONArray jsonArray = geoJson.getJSONArray("features");
        System.out.println(jsonArray.size());

        for (int i = 0; i < jsonArray.size(); i++) {
            JSONArray jsonObject = jsonArray.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates");
            for (int j = 0; j < jsonObject.size(); j++) {
                JSONArray jsonArray1 = jsonObject.getJSONArray(j);
                for (int k = 0; k < jsonArray1.size(); k++) {
                    JSONArray jsonArray2 = jsonArray1.getJSONArray(k);
                    lonList.add(jsonArray2.getDouble(0));
                    latList.add(jsonArray2.getDouble(1));
                }
            }
        }

        double minLon = Collections.min(lonList);
        double maxLon = Collections.max(lonList);
        double minLat = Collections.min(latList);
        double maxLat = Collections.max(latList);
        Bounds bounds = new Bounds(minLon, maxLon, minLat, maxLat);
        jsonToXML(geoJson, bounds, geoOSMUrl, geoOSMName);


    }

    public static void jsonToXML(JSONObject geoJson, Bounds bounds, String osmUrl, String fileName) {
        JSONArray jsonArray = geoJson.getJSONArray("features");
        int row = jsonArray.size();
        lonLatMap = new ConcurrentHashMap<>(row);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject all=jsonArray.getJSONObject(i);
            JSONArray jsonObject = all.getJSONObject("geometry").getJSONArray("coordinates");
            JSONObject properties = all.getJSONObject("properties");
            for (int j = 0; j < jsonObject.size(); j++) {
                JSONArray jsonArray1 = jsonObject.getJSONArray(j);
                String propKey = "name";
                for (int k = 0; k < jsonArray1.size(); k++) {
                    JSONArray jsonArray2 = jsonArray1.getJSONArray(k);
                    double lon = jsonArray2.getDouble(0);
                    double lat = jsonArray2.getDouble(1);
                    String key = lon + "+" + lat;
                    lonLatMap.put(key, new NodeInfo(properties.getString(propKey), indexNum.getAndIncrement(), propKey, lon, lat));
                }
            }
        }

        Document document = dataDocument(bounds);
        setNode(document.getRootElement());
        for (int i = 0; i < row; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            JSONObject geometry = jsonObject.getJSONObject("geometry");
            setWay(document.getRootElement(), geometry.getJSONArray("coordinates"), jsonObject.getJSONObject("properties"), i);
        }

        String xml = document.asXML();
        document.clearContent();
        writerFoFileOSM(xml, osmUrl, fileName);
    }

    public static void writerFoFileOSM(String data, String folderPath, String fileName) {
        try {
            File folder = new File(folderPath);
            if (!folder.exists()) {
                folder.mkdirs();
            }
            BufferedWriter bufferedWriter = CommWriterFileInfo.getWriterBuffer(folderPath + "\\" + fileName, false);
            CommWriterFileInfo.writer(bufferedWriter, data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void setNode(Element osm) {
        for (Map.Entry<String, NodeInfo> node : lonLatMap.entrySet()) {
            setNodeElement(osm, node.getValue());
        }
    }

    public static Element setNodeElement(Element osm, NodeInfo nodeInfo) {
        Element node1 = osm.addElement("node");
        node1.addAttribute("id", nodeInfo.getIndex() + "");
        node1.addAttribute("visible", true + "");
        node1.addAttribute("version", 1 + "");
        node1.addAttribute("lat", nodeInfo.getY() + "");
        node1.addAttribute("lon", nodeInfo.getX() + "");
        return node1;
    }

    public static Document dataDocument(Bounds bounds) {
        Document document = DocumentHelper.createDocument();
        Element osm = document.addElement("osm");
        osm.addAttribute("version", "0.6");
        osm.addAttribute("generator", "CGImap 0.8.8 (587855 spike-08.openstreetmap.org)");
        osm.addAttribute("copyright", "OpenStreetMap and contributors");
        osm.addAttribute("attribution", "http://www.openstreetmap.org/copyright");
        osm.addAttribute("license", "http://opendatacommons.org/licenses/odbl/1-0/");

        Element boundsEl = osm.addElement("bounds");
        boundsEl.addAttribute("minlat", bounds.getMinLat() + "");
        boundsEl.addAttribute("minlon", bounds.getMaxLon() + "");
        boundsEl.addAttribute("maxlat", bounds.getMaxLat() + "");
        boundsEl.addAttribute("maxlon", bounds.getMaxLon() + "");
        boundsEl.addAttribute("id", indexNum.getAndIncrement() + "");
        boundsEl.addAttribute("version", "1");
        return document;
    }

    public static Element setWay(Element osm, JSONArray lonlatList, JSONObject properties, int i) {
        Element way = osm.addElement("way");
        way.addAttribute("id", indexNum.getAndIncrement() + "");
        way.addAttribute("visible", true + "");
        way.addAttribute("version", 1 + "");
        int lonlatSize = lonlatList.size();
        for (int j = 0; j < lonlatSize; j++) {

            JSONArray point = lonlatList.getJSONArray(j);
            for (int k = 0; k < point.size(); k++) {
                JSONArray point1 = point.getJSONArray(k);
                double lon = point1.getDouble(0);
                double lat = point1.getDouble(1);
                String key = lon + "+" + lat;
                Element nod = way.addElement("nd");
                NodeInfo nodeInfo = lonLatMap.get(key);
                nod.addAttribute("ref", nodeInfo.getIndex() + "");
            }

        }

        if (properties != null) {
            Set<String> keys = properties.keySet();
            Iterator<String> iterator = keys.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String o = properties.getString(key);
                Element tagName = way.addElement("tag");
                tagName.addAttribute("k", key);
                tagName.addAttribute("v", o);
            }
            Element tagRoadType = way.addElement("tag");
            tagRoadType.addAttribute("k", "highway");
            tagRoadType.addAttribute("v", "motorway");
        }
        return way;
    }
}
